package com.apes.fn.tms.service;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.tms.model.*;
import com.apes.fn.tms.repository.*;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.plugin.mq.annotation.Consumer;
import com.apes.framework.plugin.outbox.OutboxPayloadWrapper;
import com.apes.framework.plugin.outbox.OutboxSubscriberService;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.framework.plugin.soe.metadata.BusinessAttributeValue;
import com.apes.framework.plugin.soe.metadata.Scene;
import com.apes.framework.util.MapUtil;
import com.apes.framework.util.StringUtil;
import com.apes.pi.service.PiManager;
import com.apes.scm.contract.model.Contract;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.party.model.Corporate;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.CorporateRepository;
import com.apes.scm.masterdata.party.repository.PartyRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.repository.ProductUomRepository;
import com.apes.scm.masterdata.stock.model.Location;
import com.apes.scm.masterdata.stock.model.PhyDepot;
import com.apes.scm.masterdata.stock.repository.PhyDepotRepository;
import com.apes.scm.masterdata.stock.service.LocationService;
import com.apes.scm.pur.purchaseOrder.model.PurchaseOrder;
import com.apes.scm.pur.purchaseOrder.repository.PurchaseOrderItemRepository;
import com.apes.scm.pur.purchaseOrder.repository.PurchaseOrderRepository;
import com.apes.scm.rbac.model.LocalPermitItem;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.UserRepository;
import com.apes.scm.stock.transfer.model.Pick;
import com.apes.scm.stock.transfer.model.PickItem;
import com.apes.scm.stock.transfer.repository.PickRepository;
import com.apes.scm.stock.transfer.repository.TransferRepository;
import com.apestech.framework.json.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("waybillService")
public class WaybillService extends DomainService {
    @Autowired
    private LocationService locationService;
    @Autowired
    private BranchLineItemRepository branchLineItemRepository;
    @Autowired
    private BranchLineRepository branchLineRepository;
    @Autowired
    private WaybillRepository waybillRepository;
    @Autowired
    private PurchaseOrderRepository orderRepository;
    @Autowired
    private TransferRepository transferRepository;
    @Autowired
    private PhyDepotRepository phyDepotRepository;
    @Autowired
    private WaybillRoutePlanningRepository waybillRoutePlanningRepository;
    @Autowired
    private ProductUomRepository productUomRepository;
    @Autowired
    private WaybillPlanningPlanRepository waybillPlanningPlanRepository;
    @Autowired
    private CarInformationRepository carInformationRepository;
    @Autowired
    private CarDetailsRepository carDetailsRepository;
    @Autowired
    PartyRoleRepository partyRoleRepository;
    @Autowired
    private WaybillPlanningLogRepository waybillPlanningLogRepository;
    @Autowired
    PickRepository pickRepository;
    @Autowired
    SiteRepository siteRepository;
    @Autowired
    PostRepository postRepository;
    @Autowired
    PartyRepository partyRepository;
    @Autowired
    CorporateRepository corporateRepository;
    @Autowired
    SequenceService sequenceService;
    @Autowired
    UserRepository userRepository;
    @Autowired
    PurchaseOrderRepository purchaseOrderRepository;
    @Autowired
    private OutboxSubscriberService outboxSubscriberService;
    @Autowired
    private PiManager piManager;

    @Value("${apes.switched:false}")
    private Boolean switched;

    public Waybill create(SimpleRequest request) {
        JSONObject getOldZCDD = request.getJO();
        Waybill waybill = this.formatWaybill(getOldZCDD);
        Waybill waybill1 = waybillRepository.saveAndFlush(waybill);

//         写入运单详情
        createWaybillPlanningLog(waybill1);
        return waybill1;
    }

    public void createWaybillPlanningLog(Waybill waybill){
        // 写入运单详情
        WaybillPlanningLog waybillPlanningLog = new WaybillPlanningLog();
        waybillPlanningLog.setWaybillId(waybill);
        waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单生成！");
        waybillPlanningLogRepository.save(waybillPlanningLog);

        waybillPlanningLog = new WaybillPlanningLog();
        waybillPlanningLog.setWaybillId(waybill);
        String transportStatus = waybill.getTransportStatus();
        transportStatus = transportStatus.equals("collection") ? "待揽收" : transportStatus.equals("sendCar") ? "待派车" : transportStatus.equals("loading") ? "待装车" :
                transportStatus.equals("inTransit") ? "运输中" : transportStatus.equals("received") ? "已签收" : "";
        waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单" + transportStatus);
        waybillPlanningLogRepository.save(waybillPlanningLog);
    }

    /**
     * 老框架转储订单
     *
     * @param getOldZCDD
     */
    private Waybill formatWaybill(JSONObject getOldZCDD) {
        Waybill waybill = new Waybill();
        String gDJLXID = getOldZCDD.getString("DJLXID");
        String gLYDJLXID = getOldZCDD.getString("LYDJLXID");//新框架的來源单据类型
        waybill.setSourceBusinessType(gDJLXID);
        waybill.setSourceBusinessKey(getOldZCDD.getString("DH"));
        waybill.setCreateDate(new Date());

        String getItemSHCKID = "";
        String getMainFHCKID = "";
        if ("OLD".equals(getOldZCDD.getString("OLDFRMEDJ"))) { // 来源旧框架
            JSONObject condition = new JSONObject();
            condition.put("DDID", getOldZCDD.get("FHDDID"));
            condition.put("KQID", getOldZCDD.get("FHKQID"));
            SimpleRequest simpleRequest = new SimpleRequest();
            simpleRequest.setData(condition);
            Location FHLocation = locationService.queryTypeSal(simpleRequest);
            if (FHLocation.getPhyDepot() == null) {
                throw new RuntimeException("请设置发货物理仓库！");
            }
            condition = new JSONObject();
            condition.put("DDID", getOldZCDD.get("SHDDID"));
            condition.put("KQID", getOldZCDD.get("SHKQID"));
            simpleRequest = new SimpleRequest();
            simpleRequest.setData(condition);
            Location SHLocation = locationService.queryTypeSal(simpleRequest);
            if (SHLocation.getPhyDepot() == null) {
                throw new RuntimeException("请设置收货物理仓库！");
            }
            String eFHCKID = FHLocation.getPhyDepot().getId();
            String eSHCKID = SHLocation.getPhyDepot().getId();
            if (eSHCKID.equals(eFHCKID)) {
                throw new RuntimeException("物理仓库相同, 不生成运单");
            }
            waybill.setDeliveryAddress(FHLocation.getPhyDepot());
            waybill.setShippingAddress(SHLocation.getPhyDepot());
            getMainFHCKID = FHLocation.getPhyDepot().getId();
            getItemSHCKID = SHLocation.getPhyDepot().getId();
        } else {
            getMainFHCKID = getOldZCDD.getString("FHCKID");
            getItemSHCKID = getOldZCDD.getString("SHCKID");
            PhyDepot phyDepot = new PhyDepot();
            phyDepot.setId(getMainFHCKID);
            phyDepot.setName(getOldZCDD.getString("FHCKMC"));
            waybill.setDeliveryAddress(phyDepot);

            phyDepot = new PhyDepot();
            phyDepot.setId(getItemSHCKID);
            phyDepot.setName(getOldZCDD.getString("SHCKMC"));
            waybill.setShippingAddress(phyDepot);
        }

        if ("ZD0".equals(gDJLXID) || "ZD2".equals(gDJLXID) || "Transfer".equals(gLYDJLXID)) {
            waybill.setTransportStatus("sendCar");
        } else if ("PurchaseOrder".equals(gLYDJLXID)) {
            waybill.setTransportStatus("collection");
            waybill.setPurchaseOrder(getOldZCDD.getString("CGDDID"));
            waybill.setAimsKey(getOldZCDD.getString("MBDDID"));
            waybill.setSupplier(getOldZCDD.getObject("GYS", PartyRole.class));
            waybill.setCarryType(getOldZCDD.getObject("THFS", BusinessAttributeValue.class));
        }

        List<WaybillCargoDetails> waybillCargoDetailsSet = new ArrayList<>();
        JSONArray ITEM_Array = getOldZCDD.getJSONArray("ITEM");
        if(ITEM_Array.isEmpty()){throw new RuntimeException("运单明细不予许为空");}
        ITEM_Array.stream().forEach(item -> {
            JSONObject ZCDDMX_Obj = (JSONObject) item;
            String iSPID = ZCDDMX_Obj.getString("SPID");
            WaybillCargoDetails waybillCargoDetails = new WaybillCargoDetails();
            waybillCargoDetails.setWaybillId(waybill);
            Product product = new Product();
            product.setId(iSPID);
            product.setName(ZCDDMX_Obj.getString("SPMC"));
            waybillCargoDetails.setProductId(product);

            List<ProductUom> productUomList = productUomRepository.findAll(JpaDsl.toCriteriaByEq("uomCategory.id", iSPID, "name", ZCDDMX_Obj.getString("JLDW")));
            if (productUomList.size() == 0) {
                throw new RuntimeException("未找到相关计量单位！");
            }
            waybillCargoDetails.setProductUomId(productUomList.get(0));
            waybillCargoDetails.setNumberQty(ZCDDMX_Obj.getDoubleValue("ZCSL"));
            waybillCargoDetails.setLoadingQty(ZCDDMX_Obj.getDoubleValue("ZCSL"));
            if (StringUtils.hasText(ZCDDMX_Obj.getString("HYZT"))) waybillCargoDetails.setSourceState(SpringManager.getBean(EnumerationRepository.class).findOne(ZCDDMX_Obj.getString("HYZT")));
            if (ZCDDMX_Obj.containsKey("ZCDJ")){
                waybillCargoDetails.setPriceUnit(ZCDDMX_Obj.getDoubleValue("ZCDJ"));
                waybillCargoDetails.setLoadingPriceUnit(ZCDDMX_Obj.getDoubleValue("ZCDJ"));
            }
            waybillCargoDetailsSet.add(waybillCargoDetails);
        });
        waybill.setWaybillCargoDetailsSet(waybillCargoDetailsSet);

        /*线路规划
         * 线路类型: 混合线路
         * 支干支 或者 干支干支 或者 干干支......
         * */
        List<WaybillRoutePlanning> waybillRoutePlanningList = new ArrayList<>();
        WaybillRoutePlanning waybillRoutePlanning = new WaybillRoutePlanning();
        WaybillPlanningPlan waybillPlanningPlan = new WaybillPlanningPlan();
        List<Map> findFHBranchLine = branchLineItemRepository.findFHBranchLine(getMainFHCKID);
        if (findFHBranchLine.size() != 0) {
            Set<String> queryCKCondition = new HashSet<>();
            queryCKCondition.add("1");
            List<Map> findSHBranchLine = branchLineItemRepository.findSHBranchLine(getItemSHCKID, queryCKCondition);
            int planNumber = 0;
            if (findSHBranchLine.size() != 0) {
                BranchLine branchLine = new BranchLine();
                PhyDepot phyDepot = new PhyDepot();
                for (Map FHMap : findFHBranchLine) {
                    String iDepartureStation = FHMap.get("departure_station") != null ? FHMap.get("departure_station").toString() : "";
                    String iTerminal = FHMap.get("terminal") != null ? FHMap.get("terminal").toString() : "";
                    String iPhy_dept_id = FHMap.get("phy_Depot_id") != null ? FHMap.get("phy_Depot_id").toString() : "";
                    String iBranchLineId = FHMap.get("branch_line_id") != null ? FHMap.get("branch_line_id").toString() : "";
                    queryCKCondition.add(iBranchLineId);

                    List<WaybillRoutePlanning> waybillRoutePlanningList1 = new ArrayList<>();
                    waybillRoutePlanning = new WaybillRoutePlanning();
                    waybillRoutePlanning.setWaybillId(waybill);
                    waybillRoutePlanning.setExecutionNumber(1);
                    this.fillWaybillRoutePlanning(branchLine, phyDepot, FHMap, waybillRoutePlanning);
                    waybillRoutePlanningList1.add(waybillRoutePlanning);
                    if (("MainLine".equals(FHMap.get("line_type")) && iTerminal.equals(getItemSHCKID)) ||
                            ("BranchLine".equals(FHMap.get("line_type")) && iPhy_dept_id.equals(getItemSHCKID))) {
                        planNumber++;
                        waybillRoutePlanning.setPlanNumber(planNumber);
                        waybillRoutePlanningList.add(waybillRoutePlanning);
                        continue;
                    }
                    for (Map SHMap : findSHBranchLine) {
                        String jDepartureStation = SHMap.get("departure_station") != null ? SHMap.get("departure_station").toString() : "";
                        String jBranchLineId = SHMap.get("branch_line_id") != null ? SHMap.get("branch_line_id").toString() : "";
                        queryCKCondition.add(jBranchLineId);
                        if (iDepartureStation.equals(jDepartureStation)) {
                            continue;
                        }
                        planNumber++;
                        waybillRoutePlanning = new WaybillRoutePlanning();
                        waybillRoutePlanning.setPlanNumber(planNumber);
                        waybillRoutePlanning.setWaybillId(waybill);
                        waybillRoutePlanning.setExecutionNumber(9999);
                        this.fillWaybillRoutePlanning(branchLine, phyDepot, SHMap, waybillRoutePlanning);
                        List<WaybillRoutePlanning> setSHWaybillRoutePlanning = new ArrayList<>();
                        setSHWaybillRoutePlanning.add(waybillRoutePlanning);
                        if (("MainLine".equals(FHMap.get("line_type")) && iTerminal.equals(jDepartureStation))
                                || ("BranchLine".equals(FHMap.get("line_type")) && iPhy_dept_id.equals(jDepartureStation))) { // 终点站发货和发货的收货仓相同
                            WaybillRoutePlanning waybillRoutePlanning1 = waybillRoutePlanningList1.get(0);
                            waybillRoutePlanning1.setPlanNumber(planNumber);
                            waybillRoutePlanningList.add(waybillRoutePlanning1);
                            waybillRoutePlanningList.add(waybillRoutePlanning);
                        } else { // 不相同一直循环，直到找到或者没有返回数据
                            int k = 0;                // 用来判断对接线路是否可以循环下一条
                            int countDockingLine = 0; // 计算对接线路
                            int count = 9998;
                            String mapDepartureStation = "";
                            List<WaybillRoutePlanning> waybillRoutePlanningList2 = new ArrayList<>();
                            Set<String> queryCKCondition2 = new HashSet<>();
                            queryCKCondition2.addAll(queryCKCondition);
                            Set<String> qrySuccessBranchLine = new HashSet<>();
                            qrySuccessBranchLine.add("1");
                            String distinctSHCK = "";
                            do {
                                Set<String> qrySuccessBranchLine1 = new HashSet<>();
                                List<Map> findSHBranchLine1 = new ArrayList<>();
                                if (!mapDepartureStation.equals("") && !mapDepartureStation.equals(null)) {
                                    findSHBranchLine1 = branchLineItemRepository.findSHBranchLine(mapDepartureStation, queryCKCondition2);
                                    if (countDockingLine != 0 && findSHBranchLine1.size() == 0) { // 分线查出为0时, 判断已经成功的路线是否可以连接上
                                        findSHBranchLine1 = branchLineItemRepository.findExistsSHBranchLine(mapDepartureStation, qrySuccessBranchLine);
                                    }
                                } else {
                                    planNumber++;
                                    findSHBranchLine1 = branchLineItemRepository.findSHBranchLine(jDepartureStation, queryCKCondition2);

                                }
                                countDockingLine += findSHBranchLine1.size();
                                if (findSHBranchLine1.size() != 0) {
                                    Map map = findSHBranchLine1.get(0);
                                    String mBranchLineId = map.get("branch_line_id") != null ? map.get("branch_line_id").toString() : "";
                                    mapDepartureStation = map.get("departure_station") != null ? map.get("departure_station").toString() : "";
                                    queryCKCondition2.add(mBranchLineId);
                                    qrySuccessBranchLine1.add(mBranchLineId);
                                    if (distinctSHCK.indexOf("," + mapDepartureStation + ",") != -1) {
                                        continue;
                                    }
                                    distinctSHCK += "," + mapDepartureStation + ",";
                                    waybillRoutePlanning = new WaybillRoutePlanning();
                                    waybillRoutePlanning.setPlanNumber(planNumber);
                                    waybillRoutePlanning.setWaybillId(waybill);
                                    waybillRoutePlanning.setExecutionNumber(count--);
                                    this.fillWaybillRoutePlanning(branchLine, phyDepot, map, waybillRoutePlanning);
                                    waybillRoutePlanningList2.add(waybillRoutePlanning);

                                    if (("MainLine".equals(FHMap.get("line_type")) && iTerminal.equals(mapDepartureStation))
                                            || ("BranchLine".equals(FHMap.get("line_type")) && iPhy_dept_id.equals(mapDepartureStation))) { // 发货线路收货仓 跟 收货仓的发货仓相同
                                        WaybillRoutePlanning waybillRoutePlanning1 = new WaybillRoutePlanning();
                                        waybillRoutePlanning1.setWaybillId(waybillRoutePlanningList1.get(0).getWaybillId());
                                        waybillRoutePlanning1.setEstimatedDeliveryTime(waybillRoutePlanningList1.get(0).getEstimatedDeliveryTime());
                                        waybillRoutePlanning1.setDeliveryAddress(waybillRoutePlanningList1.get(0).getDeliveryAddress());
                                        waybillRoutePlanning1.setShippingAddress(waybillRoutePlanningList1.get(0).getShippingAddress());
                                        waybillRoutePlanning1.setLineId(waybillRoutePlanningList1.get(0).getLineId());
                                        waybillRoutePlanning1.setExecutionNumber(waybillRoutePlanningList1.get(0).getExecutionNumber());
                                        waybillRoutePlanning1.setPlanNumber(planNumber);
                                        waybillRoutePlanningList2.add(waybillRoutePlanning1);

                                        waybillRoutePlanning1 = new WaybillRoutePlanning();
                                        waybillRoutePlanning1.setWaybillId(setSHWaybillRoutePlanning.get(0).getWaybillId());
                                        waybillRoutePlanning1.setEstimatedDeliveryTime(setSHWaybillRoutePlanning.get(0).getEstimatedDeliveryTime());
                                        waybillRoutePlanning1.setDeliveryAddress(setSHWaybillRoutePlanning.get(0).getDeliveryAddress());
                                        waybillRoutePlanning1.setShippingAddress(setSHWaybillRoutePlanning.get(0).getShippingAddress());
                                        waybillRoutePlanning1.setLineId(setSHWaybillRoutePlanning.get(0).getLineId());
                                        waybillRoutePlanning1.setExecutionNumber(setSHWaybillRoutePlanning.get(0).getExecutionNumber());
                                        waybillRoutePlanning1.setPlanNumber(planNumber);
                                        waybillRoutePlanningList2.add(waybillRoutePlanning1);

                                        if (distinctSHCK.indexOf("," + setSHWaybillRoutePlanning.get(0).getDeliveryAddress().getId() + ",") == -1
                                                && distinctSHCK.indexOf("," + waybillRoutePlanningList1.get(0).getDeliveryAddress().getId() + ",") == -1) {
                                            waybillRoutePlanningList.addAll(waybillRoutePlanningList2);
                                            qrySuccessBranchLine.addAll(qrySuccessBranchLine1);
                                        }

                                        count = 9998;
                                        distinctSHCK = "";
                                        mapDepartureStation = "";
                                        waybillRoutePlanningList2 = new ArrayList<>();
                                        if (countDockingLine > 0) {
                                            k = 2;
                                        } else {
                                            k = 1;
                                        }
                                    } else if (countDockingLine == 0) {
                                        k = 1;
                                        count = 9998;
                                        distinctSHCK = "";
                                        waybillRoutePlanningList2 = new ArrayList<>();
                                    } else if (countDockingLine > 0) {
                                        k = 2;
                                    }
                                } else { // countDockingLine = 0 表示没有需要循环的数据需要跳出循环, 大于0但是查出路线为0需要继续循环找下一个站点
                                    if (countDockingLine == 0) {
                                        k = 1;
                                    } else if (countDockingLine > 0) {
                                        countDockingLine = 0;
                                        k = 2;
                                    }
                                    count = 9998;
                                    distinctSHCK = "";
                                    mapDepartureStation = "";
                                    qrySuccessBranchLine1 = new HashSet<>();
                                    waybillRoutePlanningList2 = new ArrayList<>();
                                }
                            } while (k == 2);
                        }
                        System.out.println("结束do_while！！");
                    }
                }
                if (waybillRoutePlanningList.size() == 0) {
//                    throw new RuntimeException("请配置路线！");
                }
                waybill.setWaybillRoutePlanningSet(waybillRoutePlanningList);
            } else {
                if (waybillRoutePlanningList.size() == 0) {
//                    throw new RuntimeException("请配置路线！");
                }
            }
        } else {
//            throw new RuntimeException("请配置路线！");
        }
        return waybill;
    }

    /**
     * 填充waybillRoutePlanning的数据
     *
     * @param branchLine
     * @param phyDepot
     * @param qryResult
     * @param waybillRoutePlanning
     */
    private void fillWaybillRoutePlanning(BranchLine branchLine, PhyDepot phyDepot, /*WaybillPlanningPlan waybillPlanningPlan,*/ Map qryResult, WaybillRoutePlanning waybillRoutePlanning) {
        branchLine = new BranchLine();
        branchLine.setId(qryResult.get("branch_line_id") != null ? qryResult.get("branch_line_id").toString() : "");
        branchLine.setName(qryResult.get("branch_line_name") != null ? qryResult.get("branch_line_name").toString() : "");
        waybillRoutePlanning.setLineId(branchLine);
        phyDepot = new PhyDepot();
        phyDepot.setId(/*jDepartureStation*/qryResult.get("departure_station") != null ? qryResult.get("departure_station").toString() : "");
        phyDepot.setName(qryResult.get("departure_station_name") != null ? qryResult.get("departure_station_name").toString() : "");
        waybillRoutePlanning.setDeliveryAddress(phyDepot);
        if ("MainLine".equals(qryResult.get("line_type"))) {
            phyDepot = new PhyDepot();
            phyDepot.setId(/*jTerminal*/qryResult.get("terminal").toString());
            phyDepot.setName(qryResult.get("terminal_name").toString());
            waybillRoutePlanning.setShippingAddress(phyDepot);
        } else {
            phyDepot = new PhyDepot();
            phyDepot.setId(qryResult.get("phy_depot_id").toString());
            phyDepot.setName(qryResult.get("phy_depot_name").toString());
            waybillRoutePlanning.setShippingAddress(phyDepot);
        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date formatDate = new Date();
        try {
            String estimateDeliveryTime = qryResult.get("estimateDeliveryTime") != null ? qryResult.get("estimateDeliveryTime").toString() : "";
            if (!"".equals(estimateDeliveryTime)) {
                formatDate = format.parse(estimateDeliveryTime);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        waybillRoutePlanning.setEstimatedDeliveryTime(formatDate);
    }

    /**
     * 老框架发货修改
     *
     * @param simpleRequest
     */
    public void oldFrameUpdate(SimpleRequest simpleRequest) {
        JSONObject getJO = simpleRequest.getJO();
        Waybill waybill = waybillRepository.findUnload(getJO.getString("ZCDH"));
        if (waybill == null) {
            throw new RuntimeException("请检查运单状态");
        }
        waybill.setOutboundOrder(getJO.getString("CKDH"));
        waybillRepository.saveAndFlush(waybill);
        if (getJO.get("updateDH") == null) {
            this.create(simpleRequest);
        }
    }

    /**
     * 老框架终止删除运单
     *
     * @param simpleRequest
     */
    public void oldFrameZZDelete(SimpleRequest simpleRequest) {
        JSONObject getJO = simpleRequest.getJO();
        Waybill waybill = waybillRepository.findUnload(getJO.getString("ZCDH"));
        if (waybill == null) throw new RuntimeException("未找到对应的运单或者出库单号已存在，转储单号：" + getJO.getString("ZCDH"));
        waybill.setTransportStatus("abrogation");
        waybillRepository.saveAndFlush(waybill);
    }

    /**
     * 采购订单/转储订单
     * 生成交货单。交货单生成运单
     * 新框架生成运单
     *
     * @param request
     */
    @Consumer(topic = "tms.waybill.setWaybill", backup = false)
    public void setWaybill(SimpleRequest request) {
        Pick pick = request.getO(Pick.class);
        // 交货单类型 为发货时 生成运单
        if (waybillRepository.findAll(JpaDsl.toCriteriaByEq("sourceBusinessKey", pick.getOrigin())).size() > 0) return;
        String operation = pick.getOperation();
        if (operation.equals("receipt")) return;
        JSONObject object = new JSONObject();
        String originBusinessType = pick.getOriginBusinessType();
        if(originBusinessType==null)throw new RuntimeException("生成运单时来源单据类型不能为空。");
        String origin = pick.getOrigin();

        String innerBusinessType = pick.getInnerBusinessType();
        String id = pick.getId();
        // 来源为采购订单时 第一期 始发站为 中转站
        if (originBusinessType.equals("PurchaseOrder")) {
            PurchaseOrder purchaseOrder = orderRepository.findOne(origin);
            // 1、仅赋能公司从外部供应商采购的订单才生成运单。（PartyRole里面没有公司角色的供应商）
            PartyRole company = partyRoleRepository.findOne(purchaseOrder.getCompany().getId());
            PartyRole supplier = partyRoleRepository.findOne(purchaseOrder.getSupplier().getId());
            PartyRole supCompany = partyRoleRepository.findByPartyIdAndRoleId(supplier.getParty().getId(), "Company");
            Corporate party = corporateRepository.findByParty(company.getParty());
            Contract contract = purchaseOrder.getContract();
            Scene scene = purchaseOrder.getScene();
            // 当采购订单的合同 是 平台供应服务协议 且 业务凭证是 标准采购 由 采购订单生成运单。（因其属于需揽件的运单。）
            if (contract.getContractType().getCode().equals("platform") && scene.getName().equals("标准采购")) return;
            if (party.getOperation().getDescription().equals("赋能店") && supCompany == null) {
                //当采购合同的结算方式为门店现金时不生成运单
                if (purchaseOrder.getContract().getSettlementType().getCode().equals("deptCash")) {
                    return;
                }
                // 从旧框架生成的采购订单不生成运单
                if (purchaseOrder.getSourceType() != null && (purchaseOrder.getSourceType().equals("PurchaseReturnApply") || purchaseOrder.getSourceType().equals("XC0"))) {
                    return;
                }
                object.put("DJLXID", innerBusinessType);
                object.put("LYDJLXID", originBusinessType);
                object.put("CGDDID", origin);
                object.put("GYS", purchaseOrder.getSupplier());
                object.put("THFS", purchaseOrder.getCarryType());
                object.put("DH", id);
                Site site = siteRepository.findOne(purchaseOrder.getSiteId());
                String sitePhyDepotId = "", sitePhyDepotName = "";
                if (site != null) {
                    sitePhyDepotId = site.getPhyDepot().getId();
                    sitePhyDepotName = site.getPhyDepot().getName();
                }
                Location receiptLocation = purchaseOrder.getLocation(); // 收货仓库
                PhyDepot phyDepot = phyDepotRepository.find(null, /*"中转站物理仓"*/sitePhyDepotName, PageRequest.of(0, 1)).stream().findFirst().orElse(new PhyDepot());
                object.put("FHCKID", Optional.ofNullable(phyDepot.getId()).orElse(null));
                object.put("FHCKMC", Optional.ofNullable(phyDepot.getName()).orElse(null));
                object.put("SHCKID", Optional.ofNullable(receiptLocation.getPhyDepot().getId()).orElseThrow(() -> new RuntimeException("找不到收货仓库！")));
                object.put("SHCKMC", Optional.ofNullable(receiptLocation.getPhyDepot().getName()).orElseThrow(() -> new RuntimeException("找不到收货仓库！")));
                JSONArray ITEM_Array = setItemArray(pick);
                object.put("ITEM", ITEM_Array);
                SimpleRequest request1 = new SimpleRequest();
                request1.setData(object);
                this.create(request1);
            }
        }
    }

    public JSONArray setItemArray(Pick pick) {
        JSONArray ITEM_Array = new JSONArray();
        pick.getPickItems().stream().forEach(pickItem -> {
            JSONObject item = new JSONObject();
            item.put("SPID", pickItem.getProduct().getId());
            item.put("SPMC", pickItem.getProduct().getName());
            item.put("JLDWID", pickItem.getUom().getId());
            item.put("JLDW", pickItem.getUom().getName());
            item.put("ZCSL", pickItem.getOrderedQty());
            ITEM_Array.add(item);

        });
        return ITEM_Array;
    }


    /**
     * 采购订单生成运单
     * 新框架生成运单
     *
     * @param request
     */
    public void setWaybillFormPurchase(SimpleRequest request) {
        PurchaseOrder purchaseOrder = request.getO(PurchaseOrder.class);

        if (purchaseOrder == null || purchaseOrder.getSupplier().getParty().getName().indexOf("巴图鲁") != -1) return;
        List<Waybill> waybills = waybillRepository.findAll(JpaDsl.toCriteriaByEq("purchaseOrder", purchaseOrder.getId()));
        if (!waybills.isEmpty()) return;

        String contractTypeId = purchaseOrder.getContract().getContractType().getId();
        if (switched) {
            if (!("confirmed".equals(purchaseOrder.getState()) && "PO001".equals(purchaseOrder.getScene().getId()))) return;
        } else {
            if (!("confirmed".equals(purchaseOrder.getState()) && "PO001".equals(purchaseOrder.getScene().getId()) && "Contract.contractType.platform".equals(contractTypeId))) return;
        }

        purchaseOrder = purchaseOrderRepository.findOne(purchaseOrder.getId());
        JSONObject object = new JSONObject();

        // 1、仅赋能公司从外部供应商采购的订单才生成运单。（PartyRole里面没有公司角色的供应商）
        PartyRole company = partyRoleRepository.findOne(purchaseOrder.getCompany().getId());
        PartyRole supplier = partyRoleRepository.findOne(purchaseOrder.getSupplier().getId());
        PartyRole supCompany = partyRoleRepository.findByPartyIdAndRoleId(supplier.getParty().getId(), "Company");
        Corporate party = corporateRepository.findByParty(company.getParty());

//        if (party.getOperation()!=null && "001073".equals(party.getOperation().getId()) && supCompany == null) {
            //当采购合同的结算方式为门店现金时不生成运单
            if (purchaseOrder.getContract().getSettlementType().getCode().equals("deptCash")) {
                return;
            }
            // 从旧框架生成的采购订单不生成运单
            if (purchaseOrder.getSourceType() != null && (purchaseOrder.getSourceType().equals("PurchaseReturnApply") || purchaseOrder.getSourceType().equals("XC0"))) {
                return;
            }
            object.put("DJLXID", "PurchaseOrder");
            object.put("LYDJLXID", purchaseOrder.getInnerBusinessType());
            object.put("CGDDID", purchaseOrder.getId());
            object.put("MBDDID", purchaseOrder.getSource() != null ? purchaseOrder.getSource() : purchaseOrder.getOrigin()); //容错处理，处理前期数据
            object.put("GYS", purchaseOrder.getSupplier());
            object.put("THFS", purchaseOrder.getCarryType());
            object.put("DH", purchaseOrder.getId());

            String sitePhyDepotName = "中转站物理仓";
            if (purchaseOrder.getSiteId() != null) {
                Site site = siteRepository.findOne(purchaseOrder.getSiteId());
                if (site != null) {
                    sitePhyDepotName = site.getPhyDepot().getName();
                }
            }

            Location receiptLocation = purchaseOrder.getLocation(); // 收货仓库
            PhyDepot phyDepot = phyDepotRepository.find(null, /*"中转站物理仓"*/sitePhyDepotName, PageRequest.of(0, 1)).stream().findFirst().orElse(new PhyDepot());
            object.put("FHCKID", Optional.ofNullable(phyDepot.getId()).orElse(null));
            object.put("FHCKMC", Optional.ofNullable(phyDepot.getName()).orElse(null));
            object.put("SHCKID", Optional.ofNullable(receiptLocation.getPhyDepot().getId()).orElseThrow(() -> new RuntimeException("找不到收货仓库！")));
            object.put("SHCKMC", Optional.ofNullable(receiptLocation.getPhyDepot().getName()).orElseThrow(() -> new RuntimeException("找不到收货仓库！")));
            JSONArray ITEM_Array = new JSONArray();
            purchaseOrder.getPurchaseItems().stream().forEach(pickItem -> {
                JSONObject item = new JSONObject();
                item.put("SPID", pickItem.getProduct().getId());
                item.put("SPMC", pickItem.getProduct().getName());
                item.put("JLDWID", pickItem.getUom().getId());
                item.put("JLDW", pickItem.getUom().getName());
                item.put("ZCSL", pickItem.getProductUomQty());
                item.put("ZCDJ", pickItem.getPriceUnit());
                if (pickItem.getSourceState() != null) item.put("HYZT", pickItem.getSourceState().getId());
                System.out.println("-----------------");
                ITEM_Array.add(item);

            });
            object.put("ITEM", ITEM_Array);
            SimpleRequest request1 = new SimpleRequest();
            request1.setData(object);
            Waybill waybill = this.create(request1);
//        }
    }

    /**
     * 交货单发货时。修改运单的商品数据
     *
     * @param request
     */
    @Listener(topic = "event:tms.waybill.setWaybillCargoDetails")
    public void setWaybillCargoDetails(SimpleRequest request) {
        Pick pick = request.getO(Pick.class);
        Set<PickItem> pickItemSet = pick.getPickItems();
        // 交货单类型 为发货时 生成运单
        if (pick.getOperation().equals("deliver")) {
            List<Waybill> waybillList = waybillRepository.findBySourceBusinessKeyAndSourceBusinessType(pick.getId(), pick.getInnerBusinessType());
            waybillList.forEach(waybill -> {
                List<WaybillCargoDetails> waybillCargoDetailsList = waybill.getWaybillCargoDetailsSet();
                waybillCargoDetailsList.stream().forEach(waybillCargoDetails -> {
                    Product product = waybillCargoDetails.getProductId();
                    PickItem item = pickItemSet.stream().filter(pickItem -> pickItem.getProduct() == product).findFirst().get();
                    waybillCargoDetails.setLoadingQty(item.getQtyDone());
                });
                Iterator<WaybillCargoDetails> it = waybill.getWaybillCargoDetailsSet().iterator();
                while (it.hasNext()) {
                    WaybillCargoDetails pickItem = it.next();
                    if (pickItem.getLoadingQty() == 0) {
                        it.remove();
                    }
                }
            });
        }

    }

    /**
     * 运单货物详情
     *
     * @param request
     * @return
     */
    public Waybill findByWaybill(SimpleRequest request) {
        JSONObject object = request.getJO();
        JSONObject node = object.getJSONObject("node");
//        JSONObject node =  conditionModel.getJSONObject("node");
        String waybillId = String.valueOf(node.get("waybillId"));
//        String waybillId = request.get("waybillId");
        return waybillRepository.findOne(waybillId);
    }

    /**
     * 获取当前登录角色的操作站点的物理仓列表
     *
     * @param request
     * @return
     */
    public List<String> findSite(SimpleRequest request) {
        JSONObject jsonObject = request.get("site");
        List<String> stringList = new ArrayList<>();
        if (jsonObject == null) {
            List<LocalPermitItem> list = postRepository.findOne(request.getPostId()).getLocalPermit().getLocalPermitItems()
                    .stream().filter(localPermitItem -> localPermitItem.getType().getId().equals("pt_site") &&
                            localPermitItem.getPurpose().getId().equals("pp_operate")).collect(Collectors.toList());
            if (list.isEmpty()) {
                List<Site> siteList = siteRepository.findAll();
                siteList.forEach(site -> {
                    stringList.add(site.getPhyDepot().getId());
                });
            } else {
                list.forEach(localPermitItem -> {
                    Site site = siteRepository.findOne(localPermitItem.getOrgId());
                    stringList.add(site.getPhyDepot().getId());
                });
            }
        } else {
            stringList.add(jsonObject.getObject("phyDepot", PhyDepot.class).getId());

        }
        return stringList;

    }

    /**
     * 查询未指派任务
     *
     * @param request
     * @return
     */
    public List findByUnassigned(SimpleRequest request) {
        List<String> stringList = findSite(request);
        // 查询待派车的运单列表
        List<Waybill> waybillList = waybillRepository.findAllByTransportStatus("sendCar");
//        this.invoke();
        waybillList.addAll(waybillRepository.findAllByTransportStatus("temporary"));
        List<WaybillRoutePlanning> waybillRoutePlanningSet = new ArrayList();
        List<Map> list = new ArrayList();
        waybillList.stream().forEach(waybill -> {
            //判断运单是否是第一次指派 是则选择运单方案最快的方案里的执行顺序号最小的 否则筛选出待派车状态中执行顺序号最小的
            List<WaybillPlanningPlan> waybillPlanningPlanList = waybillPlanningPlanRepository.findByWaybillId(waybill);
            if (waybillPlanningPlanList.isEmpty()) {
                // 查询出该运单下 方案列表中各自最后执行的线路规划列表 从中选出最近的预计到达时间 然后根据该运单与线路规划方案号选出最小的线路规划
                List<WaybillRoutePlanning> waybillRoutePlanningList = waybillRoutePlanningRepository.findByWaybillId(waybill.getId());
                Optional<WaybillRoutePlanning> waybillRoutePlanning = waybillRoutePlanningList.stream()
//                        .filter(waybillRoutePlanning1 -> waybillRoutePlanning1.getEstimatedDeliveryTime().after(new Date()))
//                        .filter(waybillRoutePlanning1 -> waybillRoutePlanning1.getDeliveryAddress()==phyDepot)
                        .min(Comparator.comparing(WaybillRoutePlanning::getEstimatedDeliveryTime));
                WaybillRoutePlanning waybillRoutePlanning2 = waybillRoutePlanning.orElse(new WaybillRoutePlanning());
                if (waybillRoutePlanning2.getId() != null && stringList.contains(waybill.getDeliveryAddress().getId())) {
                    List<WaybillRoutePlanning> planNumberList = waybillRoutePlanningRepository.findByWaybillIdAndPlanNumber(waybill, waybillRoutePlanning2.getPlanNumber());
                    Optional<WaybillRoutePlanning> routePlanning = planNumberList.stream().min(Comparator.comparing(WaybillRoutePlanning::getExecutionNumber));
                    WaybillRoutePlanning routePlanning2 = routePlanning.orElse(new WaybillRoutePlanning());
                    waybillRoutePlanningSet.add(routePlanning2);
                }
            } else {
                Optional<WaybillPlanningPlan> planningPlan = waybillPlanningPlanList.stream()
                        .filter(waybillPlanningPlan -> waybillPlanningPlan.getStatus().equals("sendCar"))
                        .min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber));
                WaybillPlanningPlan planningPlan2 = planningPlan.orElse(new WaybillPlanningPlan());
                if (planningPlan2.getId() != null && stringList.contains(planningPlan2.getDeliveryAddress().getId())) {
                    WaybillRoutePlanning planning = waybillRoutePlanningRepository.findByWaybillIdAndPlanNumberAndExecutionNumber(planningPlan2.getWaybillId(), planningPlan2.getPlanNumber(), planningPlan2.getExecutionNumber());
                    waybillRoutePlanningSet.add(planning);
                }
            }

        });
        Map<BranchLine, List<WaybillRoutePlanning>> waybillRouteplannings = waybillRoutePlanningSet.stream().collect(Collectors.groupingBy(WaybillRoutePlanning::getLineId));

        waybillRouteplannings.forEach((k, v) -> {
            Map newMap = new HashMap();
            v.sort(Comparator.comparing(waybillRoutePlanning ->
                    waybillRoutePlanning.getWaybillId().getId()));
            newMap.put("branchLineId", k);
            newMap.put("waybillRouteplanningList", v);
            newMap.put("totalWaybill", v.size());
            list.add(newMap);
        });
        List newList = new ArrayList();
        int totalWaybill = list.stream().mapToInt(map -> (int) map.get("totalWaybill")).sum();
        Map unassignedMap = new HashMap();
        unassignedMap.put("id", "findByUnassigned");
        unassignedMap.put("name", "未指派任务");
        unassignedMap.put("num", totalWaybill);
        unassignedMap.put("data", list);
        newList.add(unassignedMap);
        return newList;
    }

    /**
     * 查询未指派任务详情
     *
     * @param request
     * @return
     */
    public List findByUnassignedDetail(SimpleRequest request) {
        // 待指派任务 查询的线路详情
//        BranchLine branchLine = request.getO("branchLinName",BranchLine.class);
        List<WaybillRoutePlanning> waybillRoutePlanningList = request.getA("waybillRouteplanningList", WaybillRoutePlanning.class);
        waybillRoutePlanningList.sort(Comparator.comparing(waybillRoutePlanning -> waybillRoutePlanning.getWaybillId().getId()));
        List<Map> list = new ArrayList();
        for (int i = waybillRoutePlanningList.size() - 1; i >= 0; i--) {
            WaybillRoutePlanning waybillRoutePlanning = waybillRoutePlanningList.get(i);
            Map map = MapUtil.mapper(
                    "waybill", waybillRoutePlanning.getWaybillId(),
                    "waybillRoutePlanning", waybillRoutePlanning
            );
            map.put("transit", false);
            if (waybillRoutePlanning.getExecutionNumber() == 1) {
                List<WaybillRoutePlanning> planNumberList = waybillRoutePlanningRepository.findByWaybillIdAndPlanNumber(waybillRoutePlanning.getWaybillId(), waybillRoutePlanning.getPlanNumber());
                if (planNumberList.size() > 1) {
                    map.put("transit", true);
                }
            }
            // 不是最后一次执行的方案线路
            if (waybillRoutePlanning.getExecutionNumber() > 1 && waybillRoutePlanning.getExecutionNumber() != 9999) {
                map.put("transit", true);
            }
            list.add(map);
        }

        return list;
    }


    /**
     * 指派后刷新
     *
     * @param request
     * @return
     */
    public List unassignedDetail(SimpleRequest request) {
        // 待指派任务 查询的线路详情
//        BranchLine branchLine = request.getO("branchLinName",BranchLine.class);
        List<WaybillRoutePlanning> waybillRoutePlanningList = request.getA("waybillRouteplanningList", WaybillRoutePlanning.class);
        waybillRoutePlanningList.sort(Comparator.comparing(waybillRoutePlanning -> waybillRoutePlanning.getWaybillId().getId()));
        List<Map> list = new ArrayList();
        for (int i = waybillRoutePlanningList.size() - 1; i >= 0; i--) {
            WaybillRoutePlanning waybillRoutePlanning = waybillRoutePlanningList.get(i);
            Waybill waybill = waybillRepository.findOne(waybillRoutePlanning.getWaybillId().getId());
            if ("sendCar".equals(waybill.getTransportStatus())) {
                Map map = MapUtil.mapper(
                        "waybill", waybillRoutePlanning.getWaybillId(),
                        "waybillRoutePlanning", waybillRoutePlanning
                );
                map.put("transit", false);
                if (waybillRoutePlanning.getExecutionNumber() > 1) {
                    map.put("transit", true);
                }
                list.add(map);
            }

        }
        return list;
    }

    /**
     * 根据司机查已指派未完成的派车单
     *
     * @param request
     * @return
     */
    public Map findCarInformationByChauffeur(SimpleRequest request) {
        Chauffeur chauffeur = request.getO("chauffeur", Chauffeur.class);
        List<CarInformation> chauffeurIdAndStatus = carInformationRepository.findAllByChauffeurIdAndStatus(chauffeur, "assigned");
        List<Map> list = new ArrayList();
        if (chauffeurIdAndStatus.isEmpty()) {
            Map newMap = new HashMap();
            newMap.put("carInformationId", "");
            return newMap;
        } else {
            chauffeurIdAndStatus.stream().forEach(carInformation -> {
                Map newMap = new HashMap();
                newMap.put("carInformationId", carInformation.getId());
                list.add(newMap);

            });
            return list.get(0);
        }
    }


    /**
     * 根据派车单查询运单列表
     *
     * @param request
     */
    public JSONObject findWaybillListByCarInformation(SimpleRequest request) {
        String carInformationId = request.get("carInformation");
        CarInformation carInformation = carInformationRepository.findOne(carInformationId);
        List<CarDetails> carDetailsList = carDetailsRepository.findAllByCarInformationId(carInformation);
        List<Waybill> waybillList = carDetailsList.stream().map(CarDetails::getWaybillId).collect(Collectors.toList());

        List<Map> waybillListMaps = new ArrayList<>();
        JSONObject map = new JSONObject();
        map.put("carInformationId", carInformation.getId());
        map.put("chauffeurId", carInformation.getChauffeurId());
        map.put("vehicleId", carInformation.getVehicleId());
        map.put("branchLineId", carInformation.getBranchLineId());
        waybillList.forEach(waybill -> {
            if (waybill != null) {
                Map map2 = new HashMap();
                map2.put("waybill", MapUtil.mapped(waybill));
                map2.put("transit", false);
                List<WaybillPlanningPlan> waybillPlanningPlanList = waybillPlanningPlanRepository.findByWaybillId(waybill);
                waybillPlanningPlanList.stream().sorted(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber));
                // 当前执行的线路方案
                WaybillPlanningPlan waybillPlanningPlan = waybillPlanningPlanList.stream().filter(planningPlan ->
                        "inTransit".equals(planningPlan.getStatus()) || "loading".equals(planningPlan.getStatus()))
                        .min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber)).get();
                // 最后执行的线路方案
                WaybillPlanningPlan planningPlan = waybillPlanningPlanList.get(waybillPlanningPlanList.size() - 1);
                if (waybillPlanningPlan != planningPlan) {
                    map2.put("transit", true);
                }
                waybillListMaps.add(map2);
            }
        });

        map.put("waybillList", waybillListMaps);
        return map;
    }

    /**
     * 确定指派任务
     * 生成派车单 回写 运单线路规范
     *
     * @param request
     * @return
     */
    public boolean assigned(SimpleRequest request) {
        // 指派任务 得将 司机，车辆，线路，运单列表一起带过来
        Chauffeur chauffeur = request.getO("chauffeur", Chauffeur.class);
//        CarInformation carInformation = request.getO("carInformation",CarInformation.class);
        Vehicle vehicle = request.getO("vehicle", Vehicle.class);
        JSONArray assignedList = request.get("assignedList");
        List<CarInformation> chauffeurIdAndStatus = carInformationRepository.findAllByChauffeurIdAndStatus(chauffeur, "assigned");
//        if (!chauffeurIdAndStatus.isEmpty()) throw new RuntimeException("当前司机已有未完成的派车单。");
        List<CarInformation> vehicleIdAndStatus = carInformationRepository.findAllByVehicleIdAndStatus(vehicle, "assigned");
//        if (!vehicleIdAndStatus.isEmpty()) throw new RuntimeException("当前车辆已有未完成的派车单。");
        String branchLine = new String();
        List<WaybillRoutePlanning> waybillRouteplanningList = new ArrayList<>();
        for (int j = 0; j < assignedList.size(); j++) {
            JSONObject map = assignedList.getJSONObject(j);
            String branchLinName = null;
            try {
                branchLinName = JSON.toJSON(map.get("branchLineId")).getString("name");
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (j == 0) {
                branchLine = branchLinName;
            } else {
                branchLine = branchLine + "," + branchLinName;
            }
            JSONArray waybillRouteList = map.getJSONArray("waybillRouteplanningList");
            for (int w = 0; w < waybillRouteList.size(); w++) {
                waybillRouteplanningList.add(waybillRouteList.getObject(w, WaybillRoutePlanning.class));
            }
//            List<WaybillRoutePlanning> routeplanningList = (List<WaybillRoutePlanning>)map.get("waybillRouteplanningList");
//            waybillRouteplanningList.addAll(routeplanningList);

        }

        CarInformation carInformation = new CarInformation();
        carInformation.setStatus("assigned");
        carInformation.setBranchLineId(branchLine);
        carInformation.setChauffeurId(chauffeur);
        carInformation.setVehicleId(vehicle);
        carInformation = carInformationRepository.saveAndFlush(carInformation);

        for (WaybillRoutePlanning waybillRouteplanning : waybillRouteplanningList) {
            WaybillPlanningPlan waybillPlanningPlan = waybillPlanningPlanRepository.findByWaybillIdAndPlanNumberAndExecutionNumber(
                    waybillRouteplanning.getWaybillId(), waybillRouteplanning.getPlanNumber(), waybillRouteplanning.getExecutionNumber()
            );
            if (waybillPlanningPlan != null) {
                waybillPlanningPlan.setStatus("loading");
                waybillPlanningPlan.setCarInformationId(carInformation);
                waybillPlanningPlan = waybillPlanningPlanRepository.saveAndFlush(waybillPlanningPlan);
                Waybill waybill = waybillRepository.findOne(waybillPlanningPlan.getWaybillId().getId());
                checkTransportStatus(waybill.getId());
                waybill.setTransportStatus("loading");
                waybill.setExecutionNumber(waybill.getExecutionNumber() + 1);
//                waybill = waybillRepository.saveAndFlush(waybill);
                CarDetails carDetails = setCarDetails(waybillPlanningPlan, waybillPlanningPlan.getLineId(), carInformation);

                WaybillPlanningLog waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                waybillPlanningLog.setNotes("货物已指派给" + chauffeur.getName() + ",派车单" + carInformation.getId() + "已生成！");
                waybillPlanningLogRepository.save(waybillPlanningLog);

                waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                String transportStatus = waybill.getTransportStatus();
                transportStatus = transportStatus.equals("collection") ? "待揽收" : transportStatus.equals("sendCar") ? "待派车" : transportStatus.equals("loading") ? "待装车" :
                        transportStatus.equals("inTransit") ? "运输中" : transportStatus.equals("received") ? "已签收" : "";
                waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单" + transportStatus);
                waybillPlanningLogRepository.save(waybillPlanningLog);
            } else {
                List<WaybillRoutePlanning> waybillRoutePlanningList = waybillRoutePlanningRepository.findByWaybillId(waybillRouteplanning.getWaybillId().getId());
                Optional<WaybillRoutePlanning> waybillRoutePlanning = waybillRoutePlanningList.stream()
//                        .filter(waybillRoutePlanning1 -> waybillRoutePlanning1.getEstimatedDeliveryTime().after(new Date()))
                        .min(Comparator.comparing(WaybillRoutePlanning::getEstimatedDeliveryTime));
                waybillRoutePlanning.orElseThrow(() -> new RuntimeException("生成的方案已经过时.请联系开发重新生成。"));
                WaybillRoutePlanning waybillRoutePlanning2 = waybillRoutePlanning.get();
                List<WaybillRoutePlanning> routePlanningList = waybillRoutePlanningRepository.findByWaybillIdAndPlanNumber(waybillRoutePlanning2.getWaybillId(), waybillRoutePlanning2.getPlanNumber());
                List<WaybillPlanningPlan> planningPlans = setWaybillPlanningPlan(routePlanningList, waybillRouteplanning.getWaybillId());
                Optional<WaybillPlanningPlan> plan = planningPlans.stream().min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber));
                WaybillPlanningPlan planningPlan = plan.get();
                planningPlan.setCarInformationId(carInformation);
                planningPlan.setStatus("loading");
                waybillPlanningPlanRepository.saveAndFlush(planningPlan);
                Waybill waybill = waybillRepository.findOne(planningPlan.getWaybillId().getId());
                waybill.setTransportStatus("loading");
                waybill.setExecutionNumber(1);
                waybill.setTotalNumber(routePlanningList.size());
//                waybill = waybillRepository.saveAndFlush(waybill);
                CarDetails carDetails = setCarDetails(planningPlan, planningPlan.getLineId(), carInformation);

                WaybillPlanningLog waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                waybillPlanningLog.setNotes("货物已指派给" + chauffeur.getName() + ",派车单" + carInformation.getId() + "已生成！");
                waybillPlanningLogRepository.save(waybillPlanningLog);

                waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                String transportStatus = waybill.getTransportStatus();
                transportStatus = transportStatus.equals("collection") ? "待揽收" : transportStatus.equals("sendCar") ? "待派车" : transportStatus.equals("loading") ? "待装车" :
                        transportStatus.equals("inTransit") ? "运输中" : transportStatus.equals("received") ? "已签收" : "";
                waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单" + transportStatus);
                waybillPlanningLogRepository.save(waybillPlanningLog);
            }
        }
        this.qryWaybillDispatchCar(carInformation);
        return true;
    }

    /**
     * 确定指派任务 明细里指派
     * 生成派车单 回写 运单线路规范
     *
     * @param request
     * @return
     */
    public boolean assignedByDetail(SimpleRequest request) {
        // 指派任务 得将 司机，车辆，线路，运单列表一起带过来
        Chauffeur chauffeur = request.getO("chauffeur", Chauffeur.class);
        Vehicle vehicle = request.getO("vehicle", Vehicle.class);
        BranchLine branchLine = request.getO("branchLineId", BranchLine.class);
        String branchLineName = branchLine.getName();
        JSONArray assignedList = request.get("assignedList");
        List<CarInformation> chauffeurIdAndStatus = carInformationRepository.findAllByChauffeurIdAndStatus(chauffeur, "assigned");
//        if (!chauffeurIdAndStatus.isEmpty()) throw new RuntimeException("当前司机已有未完成的派车单。");
        List<CarInformation> vehicleIdAndStatus = carInformationRepository.findAllByVehicleIdAndStatus(vehicle, "assigned");
//        if (!vehicleIdAndStatus.isEmpty()) throw new RuntimeException("当前车辆已有未完成的派车单。");
        List<WaybillRoutePlanning> waybillRouteplanningList = new ArrayList<>();
        for (int j = 0; j < assignedList.size(); j++) {
            JSONObject map = assignedList.getJSONObject(j);
            WaybillRoutePlanning planning = map.getObject("waybillRoutePlanning", WaybillRoutePlanning.class);
            waybillRouteplanningList.add(planning);
        }
        CarInformation carInformation = new CarInformation();
        carInformation.setStatus("assigned");
        carInformation.setBranchLineId(branchLineName);
        carInformation.setChauffeurId(chauffeur);
        carInformation.setVehicleId(vehicle);
        carInformation = carInformationRepository.saveAndFlush(carInformation);

        for (WaybillRoutePlanning waybillRouteplanning : waybillRouteplanningList) {
            WaybillPlanningPlan waybillPlanningPlan = waybillPlanningPlanRepository.findByWaybillIdAndPlanNumberAndExecutionNumber(
                    waybillRouteplanning.getWaybillId(), waybillRouteplanning.getPlanNumber(), waybillRouteplanning.getExecutionNumber()
            );
            if (waybillPlanningPlan != null) {
                waybillPlanningPlan.setStatus("loading");
                waybillPlanningPlan.setCarInformationId(carInformation);
                waybillPlanningPlanRepository.saveAndFlush(waybillPlanningPlan);
                Waybill waybill = waybillRepository.findOne(waybillPlanningPlan.getWaybillId().getId());
                checkTransportStatus(waybill.getId());
                waybill.setTransportStatus("loading");
                waybill.setExecutionNumber(waybill.getExecutionNumber() + 1);
//                waybill = waybillRepository.saveAndFlush(waybill);
                CarDetails carDetails = setCarDetails(waybillPlanningPlan, branchLine, carInformation);

                WaybillPlanningLog waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                waybillPlanningLog.setNotes("货物已指派给" + chauffeur.getName() + ",派车单" + carInformation.getId() + "已生成！");
                waybillPlanningLogRepository.save(waybillPlanningLog);

                waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                String transportStatus = waybill.getTransportStatus();
                transportStatus = transportStatus.equals("collection") ? "待揽收" : transportStatus.equals("sendCar") ? "待派车" : transportStatus.equals("loading") ? "待装车" :
                        transportStatus.equals("inTransit") ? "运输中" : transportStatus.equals("received") ? "已签收" : "";
                waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单" + transportStatus);
                waybillPlanningLogRepository.save(waybillPlanningLog);
            } else {
                // 初次指派确定行走的方案。 确定的方法：筛选出每个方案第一要走的线路的截单时间大于当前时间 且最后抵达时间是最小的 但是在生成方案时已经排除
                List<WaybillRoutePlanning> waybillRoutePlanningList = waybillRoutePlanningRepository.findByWaybillId(waybillRouteplanning.getWaybillId().getId());
                Optional<WaybillRoutePlanning> waybillRoutePlanning = waybillRoutePlanningList.stream()
//                        .filter(waybillRoutePlanning1 -> waybillRoutePlanning1.getEstimatedDeliveryTime().after(new Date()))
                        .min(Comparator.comparing(WaybillRoutePlanning::getEstimatedDeliveryTime));
                waybillRoutePlanning.orElseThrow(() -> new RuntimeException("生成的方案已经过时.请联系开发重新生成。"));
                WaybillRoutePlanning waybillRoutePlanning2 = waybillRoutePlanning.get();
                List<WaybillRoutePlanning> routePlanningList = waybillRoutePlanningRepository.findByWaybillIdAndPlanNumber(waybillRoutePlanning2.getWaybillId(), waybillRoutePlanning2.getPlanNumber());
                List<WaybillPlanningPlan> planningPlans = setWaybillPlanningPlan(routePlanningList, waybillRouteplanning.getWaybillId());
                Optional<WaybillPlanningPlan> plan = planningPlans.stream().min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber));
                WaybillPlanningPlan planningPlan = plan.get();
                planningPlan.setCarInformationId(carInformation);
                planningPlan.setStatus("loading");
                waybillPlanningPlanRepository.saveAndFlush(planningPlan);
                Waybill waybill = waybillRepository.findOne(planningPlan.getWaybillId().getId());
                waybill.setTransportStatus("loading");
                waybill.setExecutionNumber(1);
                waybill.setTotalNumber(routePlanningList.size());
//                waybill = waybillRepository.saveAndFlush(waybill);
                CarDetails carDetails = setCarDetails(planningPlan, branchLine, carInformation);

                WaybillPlanningLog waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                waybillPlanningLog.setNotes("货物已指派给" + chauffeur.getName() + ",派车单" + carInformation.getId() + "已生成！");
                waybillPlanningLogRepository.save(waybillPlanningLog);

                waybillPlanningLog = new WaybillPlanningLog();
                waybillPlanningLog.setWaybillId(waybill);
                waybillPlanningLog.setCarDetailsId(carDetails);
                String transportStatus = waybill.getTransportStatus();
                transportStatus = transportStatus.equals("collection") ? "待揽收" : transportStatus.equals("sendCar") ? "待派车" : transportStatus.equals("loading") ? "待装车" :
                        transportStatus.equals("inTransit") ? "运输中" : transportStatus.equals("received") ? "已签收" : "";
                waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单" + transportStatus);
                waybillPlanningLogRepository.save(waybillPlanningLog);
            }
        }
        this.qryWaybillDispatchCar(carInformation);
        return true;
    }

    /**
     * 初次指派时将方案回写到线路规划里
     *
     * @param planningPlanList
     * @param waybill
     * @return
     */
    public List<WaybillPlanningPlan> setWaybillPlanningPlan(List<WaybillRoutePlanning> planningPlanList, Waybill waybill) {
        List<WaybillPlanningPlan> planningPlans = new ArrayList<>();
        planningPlanList.forEach(waybillRoutePlanning -> {
            WaybillPlanningPlan waybillPlanningPlan = new WaybillPlanningPlan();
            waybillPlanningPlan.setPlanNumber(waybillRoutePlanning.getPlanNumber());
            waybillPlanningPlan.setWaybillId(waybill);
            waybillPlanningPlan.setExecutionNumber(waybillRoutePlanning.getExecutionNumber());
            waybillPlanningPlan.setLineId(waybillRoutePlanning.getLineId());
            waybillPlanningPlan.setDeliveryAddress(waybillRoutePlanning.getDeliveryAddress());
            waybillPlanningPlan.setShippingAddress(waybillRoutePlanning.getShippingAddress());
//            waybillPlanningPlan.setCarInformationId();
//            waybillPlanningPlan.setLoadingTime();
            waybillPlanningPlan.setArrivalTime(waybillRoutePlanning.getEstimatedDeliveryTime());
            waybillPlanningPlan.setStatus("sendCar");
            planningPlans.add(waybillPlanningPlan);
        });
        return waybillPlanningPlanRepository.saveAll(planningPlans);
    }


    /**
     * 指派时生成派车单明细
     * 按运单此次线路规划里的收货地址
     * 按指派的线路明细的执行顺序号排序
     *
     * @return
     */
    public CarDetails setCarDetails(WaybillPlanningPlan plan, BranchLine branchLine, CarInformation carInformation) {
        CarDetails carDetails = new CarDetails();
        Waybill waybill = waybillRepository.findOne(plan.getWaybillId().getId());
        PhyDepot phyDepot = waybill.getShippingAddress();
        carDetails.setWaybillId(waybill);
        carDetails.setCarInformationId(carInformation);
        if (branchLine.getLineType().equals("MainLine")) {
            carDetails.setExecutionNumber(1);
        } else {
            Optional<BranchLineItem> lineItem = branchLine.getBranchLineItems().stream().filter(branchLineItem -> branchLineItem.getPhyDepot() == phyDepot).findFirst();
            if (lineItem.orElse(null) == null) {
                carDetails.setExecutionNumber(999);
            } else {
                carDetails.setExecutionNumber(lineItem.get().getExecutionNumber());
            }

        }
        return carDetailsRepository.saveAndFlush(carDetails);
    }

    /**
     * 查询已指派任务
     *
     * @param request
     * @return
     */
    public List findByAssigned(SimpleRequest request) {
        List<String> stringList = findSite(request);
        // 查询时间段内的 已指派 派车单
        Date startValue = (Date) request.get("startValue");
        Date endValue = (Date) request.get("endValue");
        List<Map> maps = new ArrayList<>();
        List<CarInformation> carInformationList = carInformationRepository.findAllByStatusAndCreateDateAndDesc("assigned",startValue,endValue);
        carInformationList.stream().forEach(carInformation -> {
            BranchLine branch = branchLineRepository.findByName(Arrays.asList(carInformation.getBranchLineId().split(","))).stream().findFirst().get();
            List<CarDetails> carDetailsList = carDetailsRepository.findAllByCarInformationId(carInformation);
            List<Waybill> waybillList = carDetailsList.stream().map(CarDetails::getWaybillId).collect(Collectors.toList());
            if (stringList.contains(branch.getDepartureStation().getPhyDepot().getId())) {
                Map map = MapUtil.mapper(
                        "carInformation", MapUtil.mapped(carInformation),
                        "waybillList", MapUtil.mapped(waybillList),
                        "totalWaybill", waybillList.size()
                );
                maps.add(map);
            }
        });
//
        List list = new ArrayList();
        Map assignedMap = new HashMap();
        assignedMap.put("id", "findByAssigned");
        assignedMap.put("name", "已指派任务");
        assignedMap.put("num", maps.size());
        assignedMap.put("data", maps);
        list.add(assignedMap);
        return list;
    }

    /**
     * 查询已指派任务详情
     *
     * @param request
     * @return
     */
    public List findByAssignedDetail(SimpleRequest request) {
        // 已指派任务 派车单详情
        CarInformation carInformation = request.getO("carInformation", CarInformation.class);
        List<CarDetails> carDetailsList = carDetailsRepository.findAllByCarInformationId(carInformation);
        List<Waybill> waybillList = carDetailsList.stream().map(CarDetails::getWaybillId).collect(Collectors.toList());
        List<Map> maps = new ArrayList<>();
        for (int i = waybillList.size() - 1; i >= 0; i--) {
            Waybill waybill = waybillList.get(i);
            Map map = new HashMap();
            map.put("waybill", MapUtil.mapped(waybill));
            map.put("transit", false);
            List<WaybillPlanningPlan> waybillPlanningPlanList = waybillPlanningPlanRepository.findByWaybillId(waybill);
            waybillPlanningPlanList.stream().sorted(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber));
            // 当前执行的线路方案
            WaybillPlanningPlan waybillPlanningPlan = waybillPlanningPlanList.stream().filter(planningPlan ->
                    "arrived".equals(planningPlan.getStatus()) ||
                            "inTransit".equals(planningPlan.getStatus()) || "loading".equals(planningPlan.getStatus()))
                    .min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber)).get();
            // 最后执行的线路方案
            WaybillPlanningPlan planningPlan = waybillPlanningPlanList.get(waybillPlanningPlanList.size() - 1);
            if (waybillPlanningPlan != planningPlan) {
                map.put("transit", true);
            }
            maps.add(map);
        }

        return maps;
    }


    /**
     * 查询已装货的运单
     *
     * @param request
     * @return
     */
    public List findWaybillByStatus(SimpleRequest request) {
        List<String> stringList = findSite(request);
        Date startValue = (Date) request.get("startValue");
        Date endValue = (Date) request.get("endValue");
        List<Waybill> waybillList = waybillRepository.findAllByTransportStatus("inTransit");
//        waybillList = waybillList.stream().filter(c -> c.getLoadingTime().getTime()>= startValue.getTime() && c.getLoadingTime().getTime() <= endValue.getTime()).collect(Collectors.toList());
        List<Map> maps = new ArrayList<>();
        waybillList.sort(Comparator.comparing(Waybill::getId).reversed());
        waybillList.forEach(waybill -> {
            WaybillPlanningPlan plan = waybillPlanningPlanRepository.findByWaybillIdAndStatus(waybill, "inTransit").stream()
//                    .filter(plan1 -> plan1.getShippingAddress() == phyDepot || plan1.getDeliveryAddress() == phyDepot)
                    .min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber)).orElse(new WaybillPlanningPlan());
            if (plan.getId() != null && plan.getLoadingTime().getTime() >= startValue.getTime() && plan.getLoadingTime().getTime() <= endValue.getTime()) {
                CarInformation carInformation = plan.getCarInformationId();
                if (stringList.contains(plan.getShippingAddress().getId()) || stringList.contains(plan.getDeliveryAddress().getId())) {
                    Map map = MapUtil.mapper(
                            "waybillId", waybill.getId(),
                            "carInformationId", carInformation,
                            "chauffeurId", carInformation.getChauffeurId(),
                            "vehicleId", carInformation.getVehicleId(),
                            "branchLineId", carInformation.getBranchLineId(),
                            "deliveryAddress", waybill.getDeliveryAddress(),
                            "shippingAddress", waybill.getShippingAddress(),
                            "transportStatus", waybill.getTransportStatus(),
                            "loadingTime", plan.getLoadingTime(),
//                        "planLoadingTime",plan.getLoadingTime(),
                            "arrivalTime", plan.getArrivalTime(),
                            "waybillCargoDetailsSet", waybill.getWaybillCargoDetailsSet()
                    );
                    maps.add(map);
                }
            }

        });
        List list = new ArrayList();
        Map waybillByStatusMap = new HashMap();
        waybillByStatusMap.put("id", "findWaybillByStatus");
        waybillByStatusMap.put("name", "已装货");
        waybillByStatusMap.put("num", maps.size());
        waybillByStatusMap.put("data", maps);
        list.add(waybillByStatusMap);
        return list;
    }

    /**
     * 查询已签收的运单
     *
     * @param request
     * @return
     */
    public List findWaybillByReceived(SimpleRequest request) {
        List<String> stringList = findSite(request);
        Date startValue = (Date) request.get("startValue");
        Date endValue = (Date) request.get("endValue");
//        List<Waybill> waybillList = waybillRepository.findAllByTransportStatus("received");
        Page<Waybill> waybillPage = waybillRepository.findAllByTransportStatusPage("received",PageRequest.of(0, 30));
//        waybillList = waybillList.stream().filter(c -> c.getLastUpdatedStamp().getTime()>= startValue.getTime() && c.getLastUpdatedStamp().getTime() <= endValue.getTime()).collect(Collectors.toList());
        List<Map> maps = new ArrayList<>();
//        waybillList.sort(Comparator.comparing(Waybill::getId).reversed());
        waybillPage.forEach(waybill -> {
            WaybillPlanningPlan plan = waybillPlanningPlanRepository.findByWaybillIdAndStatus(waybill, "arrived").stream()
//                    .filter(plan1 -> plan1.getShippingAddress() == phyDepot)
                    .max(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber)).orElse(new WaybillPlanningPlan());
            if (plan.getId() != null && waybill.getReceivedDate().getTime() >= startValue.getTime() && waybill.getReceivedDate().getTime() <= endValue.getTime()) {
                if (stringList.contains(plan.getShippingAddress().getId())) {
                    CarInformation carInformation = plan.getCarInformationId();
                    Long time = waybill.getLastUpdatedStamp().getTime() - waybill.getCreateDate().getTime();
                    long days = time / (1000 * 60 * 60 * 24);
                    long hours = (time - days * (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
                    long minutes = (time - days * (1000 * 60 * 60 * 24) - hours * (1000 * 60 * 60)) / (1000 * 60);
                    long second = (time - days * (1000 * 60 * 60 * 24) - hours * (1000 * 60 * 60) - minutes * (1000 * 60)) / (1000);

                    Map map = MapUtil.mapper(
                            "waybillId", waybill.getId(),
                            "carInformationId", carInformation,
                            "chauffeurId", carInformation.getChauffeurId(),
                            "vehicleId", carInformation.getVehicleId(),
                            "branchLineId", carInformation.getBranchLineId(),
                            "deliveryAddress", waybill.getDeliveryAddress(),
                            "shippingAddress", waybill.getShippingAddress(),
                            "transportStatus", waybill.getTransportStatus(),
                            "loadingTime", waybill.getLoadingTime() != null ? waybill.getLoadingTime() : "",
//                        "planLoadingTime",plan.getLoadingTime(),
                            "arrivalTime", waybill.getLastUpdatedStamp(),
                            "consumeTime", hours + ":" + minutes + ":" + second,
                            "waybillCargoDetailsSet", waybill.getWaybillCargoDetailsSet()
                    );
                    maps.add(map);
                }

            }
        });
        List list = new ArrayList<>();
        Map receivedMap = new HashMap();
        receivedMap.put("id", "findWaybillByReceived");
        receivedMap.put("name", "已签收");
        receivedMap.put("num", maps.size());
        receivedMap.put("data", maps);
        list.add(receivedMap);

        return list;
    }


    /**
     * 查询中转暂存的运单
     *
     * @param request
     * @return
     */
    public List findWaybillByTransit(SimpleRequest request) {
        List<String> stringList = findSite(request);
        // 查询中转暂存的运单 1.查出所有暂存中的运单，判断该运单下的线路规划列表大于1 。且正在运输的不是该列表下执行顺序最大的
        List<Waybill> waybillList = waybillRepository.findAllByTransportStatus("temporary");
        List<Map> maps = new ArrayList<>();
        waybillList.sort(Comparator.comparing(Waybill::getId).reversed());
        waybillList.forEach(waybill -> {
            if (stringList.contains(waybill.getShippingAddress().getId())) {
                Map map = MapUtil.mapper(
                        "waybillId", waybill.getId(),
                        "sourceBusinessKey", waybill.getSourceBusinessKey(),
                        "deliveryAddress", waybill.getDeliveryAddress(),
                        "shippingAddress", waybill.getShippingAddress(),
                        "transportStatus", waybill.getTransportStatus(),
                        "loadingTime", waybill.getLoadingTime(),
                        "transitDate", waybill.getTransitDate(),
                        "arrivalTime", waybill.getLastUpdatedStamp(),
                        "consumeTime", (waybill.getLastUpdatedStamp().getTime() - waybill.getLoadingTime().getTime()) / (1000 * 60 * 60),
                        "waybillCargoDetailsSet", waybill.getWaybillCargoDetailsSet()
                );
                maps.add(map);
            }


//                }
//            }
        });
        List list = new ArrayList<>();
        Map transitMap = new HashMap();
        transitMap.put("id", "findWaybillByTransit");
        transitMap.put("name", "中转暂存");
        transitMap.put("num", maps.size());
        transitMap.put("data", maps);
        list.add(transitMap);
        return list;
    }

    /**
     * 中转收件根据派车单查询可中转的运单列表
     *
     * @param request
     */
    public Map findTransitReceive(SimpleRequest request) {
        String carInformationId = request.get("carInformationId");
        CarInformation carInformation = carInformationRepository.findOne(carInformationId);
        if (carInformation == null) throw new RuntimeException("没有此派车单。");
        List<CarDetails> carDetailsList = carDetailsRepository.findAllByCarInformationId(carInformation);
        List<Waybill> waybillList = carDetailsList.stream().map(CarDetails::getWaybillId).collect(Collectors.toList());

        List<Map> waybillListMaps = new ArrayList<>();
        Map map = new HashMap();
        map.put("carInformationId", carInformation);
        map.put("chauffeurId", carInformation.getChauffeurId());
        map.put("vehicleId", carInformation.getVehicleId());
        map.put("branchLineId", carInformation.getBranchLineId());


        waybillList.forEach(waybill -> {
            if (waybill != null && !waybill.getTransportStatus().equals("temporary")) {
                List<WaybillPlanningPlan> waybillPlanningPlanList = waybillPlanningPlanRepository.findByWaybillId(waybill);
                waybillPlanningPlanList.stream().sorted(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber));
                // 当前执行的线路方案
                List<WaybillPlanningPlan> waybillPlanningPlanList2 = waybillPlanningPlanList.stream().filter(planningPlan -> "inTransit".equals(planningPlan.getStatus())).collect(Collectors.toList());
                if (waybillPlanningPlanList2.isEmpty()) return;
                WaybillPlanningPlan waybillPlanningPlan = waybillPlanningPlanList2.stream().min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber)).get();
                // 最后执行的线路方案
                WaybillPlanningPlan planningPlan = waybillPlanningPlanList.get(waybillPlanningPlanList.size() - 1);
                if (waybillPlanningPlan != planningPlan) {
                    Map map1 = MapUtil.mapper(
                            "waybillId", waybill.getId(),
                            "sourceBusinessKey", waybill.getSourceBusinessKey(),
                            "deliveryAddress", waybill.getDeliveryAddress(),
                            "shippingAddress", waybill.getShippingAddress(),
                            "transportStatus", waybill.getTransportStatus(),
                            "loadingTime", waybill.getLoadingTime(),
//                        "planLoadingTime",plan.getLoadingTime(),
                            "arrivalTime", waybill.getLastUpdatedStamp(),
                            "consumeTime", (waybill.getLastUpdatedStamp().getTime() - waybill.getLoadingTime().getTime()) / (1000 * 60 * 60),
                            "waybillCargoDetailsSet", waybill.getWaybillCargoDetailsSet()
                    );
                    waybillListMaps.add(map1);
                }
            }

        });

        map.put("waybillList", waybillListMaps);
        return map;
    }


    /**
     * 中转收件
     *
     * @param request
     */
    public List transitReceive(SimpleRequest request) {
        JSONObject site = request.get("site");
        JSONArray jsonArray = request.get("assignedList");
        List<Waybill> waybillList = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            Waybill waybill = waybillRepository.findOne(jsonObject.getString("waybillId"));
            waybillList.add(waybill);
        }

        List<CarInformation> carInformationArrayList = new ArrayList<>();
        waybillList.stream().forEach(waybill -> {
            List<WaybillPlanningPlan> waybillPlanningPlanList = waybillPlanningPlanRepository.findByWaybillId(waybill).stream()
                    .filter(planningPlan -> "inTransit".equals(planningPlan.getStatus()))
                    .sorted(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber))
                    .collect(Collectors.toList());
            WaybillPlanningPlan waybillPlanningPlan = waybillPlanningPlanList.get(0);
//            checkPick(waybill,waybillPlanningPlan);
            waybill.setTransportStatus("temporary");
            if (site == null) throw new RuntimeException("所属站点为空。");
            waybill.setSite(request.getO("site", Site.class));// 暂存的站点
            waybill.setTransitDate(new Date());
            waybillPlanningPlan.setStatus("arrived");
            waybillPlanningPlanRepository.saveAndFlush(waybillPlanningPlan);

            WaybillPlanningLog waybillPlanningLog = new WaybillPlanningLog();
            waybillPlanningLog.setWaybillId(waybill);
            String transportStatus = waybill.getTransportStatus();
            transportStatus = transportStatus.equals("collection") ? "待揽收" : transportStatus.equals("sendCar") ? "待派车" : transportStatus.equals("loading") ? "待装车" :
                    transportStatus.equals("inTransit") ? "运输中" : transportStatus.equals("received") ? "已签收" : transportStatus.equals("temporary") ? "暂存中转站" : "";
            waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单" + transportStatus);
            waybillPlanningLogRepository.save(waybillPlanningLog);
            carInformationArrayList.add(carInformationRepository.findOne(waybillPlanningPlan.getCarInformationId().getId()));
        });
        //判断该派车单下的所有运单是否都 已签收 当全部签收时回写派车单状态
        CarInformation carInformation = carInformationArrayList.get(0);
        List<WaybillPlanningPlan> waybillPlanningPlanList = waybillPlanningPlanRepository.findByCarInformationId(carInformation).stream()
                .filter(waybillPlanningPlan1 -> !waybillPlanningPlan1.getStatus().equals("arrived")).collect(Collectors.toList());
//        List<CarDetails> carDetailsList = carDetailsRepository.findAllByCarInformationId(carInformation );
        if (waybillPlanningPlanList.isEmpty()) {
            carInformation.setStatus("done");
        }
        return waybillList;
    }

    /**
     * 判断运单里的商品数量 与交货数量是否对应
     *
     * @param waybill
     * @param plan
     * @return
     */
    public boolean checkPick(Waybill waybill, WaybillPlanningPlan plan) {
        String sourceBusinessKey = waybill.getSourceBusinessKey();
        String sourceBusinessType = waybill.getSourceBusinessType();
        // 根据来源单据号 和 来源单据类型 查询出运单 判断运单明细的商品 与 交货单的商品是否对应
        List<WaybillCargoDetails> waybillCargoDetailsSet = waybill.getWaybillCargoDetailsSet();
        AtomicBoolean returnStatus = new AtomicBoolean(false);
        AtomicReference<String> string = null;
        // 如果是根据交货单生成的运单 判断对比交货单的商品明细数量
        if (sourceBusinessType.equals("Pick")) {
            Pick pick = pickRepository.findOne(sourceBusinessKey);
            Set<PickItem> pickItemSet = pick.getPickItems();
            // 判断运单里的商品数量 与交货数量是否对应
            waybillCargoDetailsSet.stream().forEach(waybillCargoDetails -> {
                PickItem pickItem1 = pickItemSet.stream().filter(pickItem -> pickItem.getProduct() == waybillCargoDetails.getProductId()).findFirst().orElse(null);
                if (pickItem1.getQtyDone() != waybillCargoDetails.getLoadingQty()) {
                    returnStatus.set(true);
                    string.set(pickItem1.getProduct().getName() + waybillCargoDetails.getLoadingQty() + pickItem1.getQtyDone() + waybillCargoDetails.getProductUomId().getName());
                }
            });
        }
        //旧框架生成的运单不需要比较。因为不管发货还是签收都不可修改商品及数量
//        else { // 不是通过交货单生成的运单 是旧框架生成的 需要从旧框架获取到商品列表进行比较
//            // 调接口取旧框架的商品列表
//            JSONObject ZCDD = new JSONObject();
//            ZCDD.put("DJHM",waybill.getSourceBusinessKey());
//            String topic = "event:tms.waybill.findWaybillByZCDD";
//            JSONArray rows = (JSONArray) EventUtil.sendSynEvent(this, topic,ZCDD).stream().findFirst().get();
//        }
        if (returnStatus.get()) {
            throw new RuntimeException(string.get());
        }
        return returnStatus.get();
    }

    /**
     * 数据看板初次查询统一接口
     *
     * @param request
     * @return
     */
    public List getLocationService(SimpleRequest request) {
        // 查询未指派任务
        List list = new ArrayList();
        return list;
    }

    /**
     * 重新指派接口
     * 就是回退此运单到未指派状态
     *
     * @param request
     */
    public List<Waybill> returnWaybill(SimpleRequest request) {
        JSONArray jsonArray = request.get("waybill");
        List<Waybill> waybillList = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            Waybill waybill = jsonObject.getObject("waybill", Waybill.class);
            checkTransportStatus(waybill.getId());
            waybillList.add(waybill);
        }
        List<Waybill> returnWaybillList = new ArrayList<>();
        CarInformation carInformation = request.getO("carInformation", CarInformation.class);
        waybillList.forEach(waybill -> {
            List<WaybillPlanningPlan> waybillPlanningPlanList = waybillPlanningPlanRepository.findByWaybillId(waybill).stream()
                    .sorted(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber))
                    .collect(Collectors.toList());
            if (!"loading".equals(waybill.getTransportStatus())) {
                throw new RuntimeException("运单：" + waybill.getId() + "不在待装车状态，不予许重新指派。");
            }
            WaybillPlanningPlan waybillPlanningPlan = waybillPlanningPlanList.stream().filter(planningPlan -> "loading".equals(planningPlan.getStatus()))
                    .min(Comparator.comparing(WaybillPlanningPlan::getExecutionNumber)).get();

            waybillPlanningPlan.setStatus("sendCar");
            waybillPlanningPlan.setCarInformationId(null);
            waybillPlanningPlanRepository.saveAndFlush(waybillPlanningPlan);
            CarDetails carDetails = carDetailsRepository.findAllByWaybillIdAndCarInformationId(waybill, carInformation);
            carDetails.setWaybillId(null);
            carDetails.setCarInformationId(null);
            carDetailsRepository.save(carDetails);
            waybill.setExecutionNumber(waybill.getExecutionNumber() - 1);
            waybill.setTransportStatus("sendCar");
            returnWaybillList.add(waybillRepository.saveAndFlush(waybill));

            WaybillPlanningLog waybillPlanningLog = new WaybillPlanningLog();
            waybillPlanningLog.setWaybillId(waybill);
            String transportStatus = waybill.getTransportStatus();
            transportStatus = transportStatus.equals("collection") ? "待揽收" : transportStatus.equals("sendCar") ? "待派车" : transportStatus.equals("loading") ? "待装车" :
                    transportStatus.equals("inTransit") ? "运输中" : transportStatus.equals("received") ? "已签收" : transportStatus.equals("temporary") ? "暂存中转站" : "";
            waybillPlanningLog.setNotes("【" + phyDepotRepository.findOne(waybill.getShippingAddress().getId()).getName() + "】运单 重新指派" + transportStatus);
            waybillPlanningLogRepository.save(waybillPlanningLog);
        });
        List<CarDetails> carDetailsList = carDetailsRepository.findAllByCarInformationId(carInformation);
        List<CarDetails> carDetailss = new ArrayList<>();
        carDetailsList.forEach(carDetails -> {
           String status = carDetails.getWaybillId().getTransportStatus();
           if(!(status.equals("received") || status.equals("temporary"))){
               carDetailss.add(carDetails);
           }
        });

        if (carDetailss.isEmpty() || carDetailss == null) {
            carInformation.setStatus("done");
            carInformationRepository.saveAndFlush(carInformation);
        }
        return returnWaybillList;
    }

    /**
     * 定时更新运单方案送达时间
     *
     * @param simpleRequest
     */
    public void updateWaybillRoutePlanningDate(SimpleRequest simpleRequest) {
        waybillRoutePlanningRepository.updateWaybillRoutePlanning();
    }

    /**
     * 查询待揽件的运单
     *
     * @param request
     * @return
     */
    public List findByCollection(SimpleRequest request) {
        JSONObject getJO = request.getJO();
        List getDDXXArray = getOldDdxx(getJO.getString("bjz"));
        List<String> stringList = findSite(request);
        String supplier_id  = request.get("supplier_id");
        String aims_key = request.get("aimsKey").toString();
        Date startValue = (Date) request.get("startValue");
        Date endValue = (Date) request.get("endValue");
        List<Waybill> waybillList = new ArrayList<>();
        if (supplier_id!=null && !aims_key.equals("0")){
            waybillList = waybillRepository.findAllByTransportStatusAndPurchaseOrderAndSupplier("collection",aims_key,supplier_id,startValue,endValue);
        }else if (supplier_id!=null &&  aims_key.equals("0")){
            waybillList = waybillRepository.findAllByTransportStatusAndSupplier("collection",supplier_id,startValue,endValue);
        }else if (supplier_id==null && !aims_key.equals("0")){
            waybillList = waybillRepository.findAllByTransportStatusAndPurchaseOrder("collection",aims_key,startValue,endValue);
        } else {
            waybillList = waybillRepository.findAllByTransportStatusAndCreateDate("collection",startValue,endValue);
        }
        waybillList = waybillList.stream().filter(waybill -> stringList.contains(waybill.getShippingAddress().getId())).collect(Collectors.toList());

        List<Map> maps = new ArrayList<>();
        List<Map> list = new ArrayList<>();

        for (int i = 0; i < waybillList.size(); i++) {
            Waybill waybill = waybillList.get(i);
            if (getDDXXArray.size() != 0 && !getDDXXArray.contains(waybill.getShippingAddress().getOrigin())) continue;
            Map map = MapUtil.mapper(
                    "waybillId", waybill.getId(),
                    "aimsKey", waybill.getAimsKey(),
                    "purchaseOrder", waybill.getPurchaseOrder(),
                    "supplier", waybill.getSupplier(),
                    "supplierPhone", waybill.getSupplier().getParty().getInvoicePhone(),
                    "deliveryAddress", waybill.getDeliveryAddress(),
                    "shippingAddress", waybill.getShippingAddress(),
                    "transportStatus", waybill.getTransportStatus(),
                    "createDate", waybill.getCreateDate(),
                    "carryType", waybill.getCarryType()
            );
            List<Map> itemMapList = new ArrayList<>();
            List<WaybillCargoDetails> waybillCargoDetailsSet = waybill.getWaybillCargoDetailsSet();
            itemMapList = MapUtil.mapped(waybillCargoDetailsSet);
            Double reprieveTotal = 0.0;
            if (waybillCargoDetailsSet!=null && !waybillCargoDetailsSet.isEmpty()){
                reprieveTotal = waybillCargoDetailsSet.stream().reduce(0.0, (x, waybillCargoDetails) -> x + (waybillCargoDetails.getLoadingQty() * waybillCargoDetails.getLoadingPriceUnit()), Double::sum);
            }

            map.put("waybillCargoDetailsSet",itemMapList);
            map.put("reprieveTotal",reprieveTotal);
            maps.add(map);
        }

//        List collection = findByCollection(request);
        Map collectionMap = new HashMap();
        collectionMap.put("id", "findByCollection");
        collectionMap.put("name", "未揽件的运单");
        collectionMap.put("num", maps.size());
        collectionMap.put("data", maps);
        list.add(collectionMap);
        return list;
    }

    // 根据报价组获取老系统地点信息
    private List getOldDdxx(String bjz) {
        List ddids = new ArrayList();
        if (bjz != null) {
            int bjzNumber = bjz.equals("A")?0:bjz.equals("B")?1:bjz.equals("C")?2:bjz.equals("D")?3:bjz.equals("E")?4:-1;
            JSONObject resultDDXX = piManager.synErp("mdmDdxxService.queryAccordingBjz", MapUtil.mapper("BJZ", bjzNumber));
            JSONArray.parseArray(resultDDXX.get("obj").toString()).forEach(singleDDXX -> ddids.add(((JSONObject) singleDDXX).getString("DDID")));
            return ddids;
        }
        return ddids;
    }

    /**
     * 确认揽件
     *
     * @param request
     */
    public Waybill collection(SimpleRequest request) {
        String waybillId = request.get("waybillId");
        Waybill waybill = waybillRepository.findOne(waybillId);
        List<WaybillCargoDetails> waybillCargoDetailsSet = request.getA("waybillCargoDetailsSet",WaybillCargoDetails.class);
        waybill.setTransportStatus("sendCar");
        waybill.setTransitDate(new Date());
        Site site = siteRepository.findOne("000003");
        waybill.setSite(site);
        waybill.setWaybillCargoDetailsSet(waybillCargoDetailsSet);
        waybill = waybillRepository.saveAndFlush(waybill);

        // 修改采购揽件数量
        this.updatePurchaseOrderQty(waybill.getId(), waybill.getPurchaseOrder(), waybill.getWaybillCargoDetailsSet());

        // 当揽件数量小于订单数量时重新生成新运单
        backorder(waybill);
        waybillCargoDetailsSet = waybillCargoDetailsSet.stream().filter(waybillCargoDetails -> waybillCargoDetails.getLoadingQty()!=0).collect(Collectors.toList());
        checkPriceUnit(request,waybill,waybillCargoDetailsSet);
        waybill.setWaybillCargoDetailsSet(waybillCargoDetailsSet);
        waybill = waybillRepository.saveAndFlush(waybill);
        this.qryWaybillPackage(waybill);
        return waybill;
    }

    /**
     * 修改采购揽件数量
     * @param purchaseOrderId
     * @param waybillCargoDetailsSet
     */
    private void updatePurchaseOrderQty(String waybillId, String purchaseOrderId, List<WaybillCargoDetails> waybillCargoDetailsSet) {
        PurchaseOrder purchaseOrder = purchaseOrderRepository.findOne(purchaseOrderId);
        JSONArray cgddArray = new JSONArray();
        waybillCargoDetailsSet.forEach(waybillCargoDetails -> {
            purchaseOrder.getPurchaseItems().stream().filter(purchaseOrderItem -> {
                String wProductId = waybillCargoDetails.getProductId().getId();
                String pProductId = purchaseOrderItem.getProduct().getId();
                if (wProductId.equals(pProductId)) {
                    purchaseOrderItem.setSolicitationQty(purchaseOrderItem.getSolicitationQty() + waybillCargoDetails.getLoadingQty());
                    this.makeupOldCGDD(purchaseOrder.getSource(), purchaseOrder.getSourceType(), pProductId, waybillCargoDetails.getLoadingQty(), cgddArray);
                }
                return wProductId.equals(pProductId);
            }).findAny();
        });
        purchaseOrderRepository.save(purchaseOrder);

        JSONObject cgddData = new JSONObject();
        cgddData.put("CGDDH", purchaseOrder.getSource());
        cgddData.put("items", cgddArray);
        outboxSubscriberService.commonSendRequest("local:waybillService.updateSolicitationQty", "updateSolicitationQty" + waybillId, cgddData);
    }

    /**
     * 组装老框架数据
     * @param cgddh
     * @param sourceType
     * @param productId
     * @param loadingQty
     * @param cgddArray
     */
    private void makeupOldCGDD(String cgddh, String sourceType, String productId, double loadingQty, JSONArray cgddArray) {
        if (!"CD0".equals(sourceType)) return;
        JSONObject cgddObj = new JSONObject();
        cgddObj.put("SPID", productId);
        cgddObj.put("SOLICITATION_QTY", loadingQty);
        cgddObj.put("CGDDH", cgddh);
        cgddArray.add(cgddObj);
    }


    private void checkPriceUnit(SimpleRequest request,Waybill waybill,List<WaybillCargoDetails> waybillCargoDetailsSet){
        AtomicBoolean isNotNull = new AtomicBoolean(false);
        String sourceBusinessKey = waybill.getSourceBusinessKey();
        String sourceBusinessType = waybill.getSourceBusinessType();
        waybillCargoDetailsSet.forEach(waybillCargoDetails -> {
            double priceUnit = waybillCargoDetails.getPriceUnit();
            double loadingPriceUnit = waybillCargoDetails.getLoadingPriceUnit();
            //如果揽件单价！=订货单价，需更新对应采购订单+ 商品的订货单价，并在采购订单日志记录“禤建昌修改订货单价”
            if (priceUnit != loadingPriceUnit){
                PurchaseOrderRepository purchaseOrderRepository =  SpringManager.getBean(PurchaseOrderRepository.class);
                PurchaseOrder purchaseOrder = purchaseOrderRepository.findOne(sourceBusinessKey);
                if (purchaseOrder!=null){
                    isNotNull.set(true);
                    purchaseOrder.getPurchaseItems().stream()
                            .filter(purchaseOrderItem -> purchaseOrderItem.getProduct()==waybillCargoDetails.getProductId())
                            .collect(Collectors.toList()).forEach(purchaseOrderItem -> {
                        purchaseOrderItem.setPriceUnit(loadingPriceUnit);
                        purchaseOrderItem.setPriceTotal(loadingPriceUnit*purchaseOrderItem.getProductUomQty());
                        SpringManager.getBean(PurchaseOrderItemRepository.class).save(purchaseOrderItem);
                    });
                }

            }
        });
        User user = (User)request.getCurrentUser();
        if (isNotNull.get()){
            sendSynEvent("event:ir.logger.create", mapper(
                    "businessType", sourceBusinessType,
                    "businessKey", sourceBusinessKey,
                    "operate", "保存采购订单",
                    "workPostName",null,
                    "remark", user.getName()+"采购揽件修改订货单价。",
                    "oaFlag", false,
                    "operator_id",user.getId()
                   ));
        }
    }

    /**
     * 当运单的来源单据终止后
     * 运单的流转
     *
     * @param request
     */
    @Consumer(topic = "tms.waybill.repeal", backup = false)
    public void repeal(SimpleRequest request ) {
        String sourceBusinessKey = request.get("sourceBusinessKey");
        String sourceBusinessType = request.get("sourceBusinessType");
        List<Waybill> waybillList = waybillRepository.findBySourceBusinessKeyAndSourceBusinessType(sourceBusinessKey, sourceBusinessType);
        waybillList.forEach(waybill -> {
            if (!waybill.getTransportStatus().equals("temporary") || !waybill.getTransportStatus().equals("loading")
                    || !waybill.getTransportStatus().equals("inTransit") || !waybill.getTransportStatus().equals("received")){
//                throw new RuntimeException("已规划线路并已指派了司机和车辆，无法终止！");
                waybill.setTransportStatus("abrogation");
                waybillRepository.save(waybill);
            }
        });

    }


    /**
     * 当运单为终止时，不能操作
     * @param id
     */
    public void checkTransportStatus(String id){
        Waybill waybill = waybillRepository.findOne(id);
        if (waybill.getTransportStatus().equals("abrogation")){
            throw new RuntimeException(waybill.getId()+"运单已经被终止，无法操作！");
        }
    }


    /**
     *  当揽件数量小于订单数量时重新生成新运单
     */
    public void backorder(Waybill waybill) {
        List<WaybillCargoDetails> waybillCargoDetailsSet = waybill.getWaybillCargoDetailsSet().stream()
                .filter(waybillCargoDetails -> waybillCargoDetails.getNumberQty() != waybillCargoDetails.getLoadingQty())
                .map(new Function<WaybillCargoDetails, WaybillCargoDetails>() {
                    @Override
                    public WaybillCargoDetails apply(WaybillCargoDetails waybillCargoDetails) {
                        WaybillCargoDetails toItem = new WaybillCargoDetails();
                        toItem.setProductId(waybillCargoDetails.getProductId());
                        toItem.setProductUomId(waybillCargoDetails.getProductUomId());
                        toItem.setLoadingQty(waybillCargoDetails.getNumberQty() - waybillCargoDetails.getLoadingQty());
                        toItem.setNumberQty(waybillCargoDetails.getNumberQty() - waybillCargoDetails.getLoadingQty());
                        toItem.setPriceUnit(waybillCargoDetails.getPriceUnit());
                        return toItem;
                    }
                }).collect(Collectors.toList());
        if (waybillCargoDetailsSet.size() == 0) return;

        JSONObject object = new JSONObject();
        object.put("DJLXID", waybill.getSourceBusinessType());
        object.put("LYDJLXID", waybill.getSourceBusinessType());
        object.put("CGDDID", waybill.getPurchaseOrder());
        object.put("MBDDID", waybill.getAimsKey());
        object.put("GYS", waybill.getSupplier());
        object.put("THFS", waybill.getCarryType());
        object.put("DH", waybill.getSourceBusinessKey());
        object.put("FHCKID", waybill.getDeliveryAddress().getId());
        object.put("FHCKMC",waybill.getDeliveryAddress().getName());
        object.put("SHCKID", waybill.getShippingAddress().getId());
        object.put("SHCKMC", waybill.getShippingAddress().getName());
        JSONArray ITEM_Array = new JSONArray();
        waybillCargoDetailsSet.stream().forEach(pickItem -> {
            JSONObject item = new JSONObject();
            item.put("SPID", pickItem.getProductId().getId());
            item.put("SPMC", pickItem.getProductId().getName());
            item.put("JLDWID", pickItem.getProductUomId().getId());
            item.put("JLDW", pickItem.getProductUomId().getName());
            item.put("ZCSL", pickItem.getNumberQty());
            item.put("ZCDJ", pickItem.getPriceUnit());
            ITEM_Array.add(item);

        });
        object.put("ITEM", ITEM_Array);
        SimpleRequest request1 = new SimpleRequest();
        request1.setData(object);
        this.create(request1);
    }

    /**
     * 揽件
     * @param waybill
     */
    private void qryWaybillPackage(Waybill waybill) {
        PurchaseOrder purchaseOrder = purchaseOrderRepository.findOne(waybill.getSourceBusinessKey());
        if (!"CD0".equals(purchaseOrder.getSourceType())) return;
        JSONObject param = new JSONObject();
        param.put("SYID", purchaseOrder.getProductRequire());
        param.put("XYID", waybill.getId());
        param.put("DJLXID", "package");
        try {
            param.put("ZXRQ_SJ", JSON.toJSONStringWithDateFormat(new Date()));
        } catch (Exception e) {
            throw new RuntimeException("日期转换失败" + param);
        }
        JSONArray itemArray = new JSONArray();
        waybill.getWaybillCargoDetailsSet().forEach(waybillCargoDetails -> {
            JSONObject item = new JSONObject();
            item.put("SPID", waybillCargoDetails.getProductId().getId());
            item.put("SL", waybillCargoDetails.getLoadingQty());
            item.put("JLDW", waybillCargoDetails.getProductUomId().getName());
            itemArray.add(item);
        });
        param.put("item", itemArray);
        outboxSubscriberService.commonSendRequest("local:WaybillService.insertWaybillWLGZ", "waybillPackage_waybillId" + waybill.getId(), param);
    }

    /**
     * 派车
     * @param carInformation
     */
    private void qryWaybillDispatchCar(CarInformation carInformation) {
        JSONArray itemArray = new JSONArray();
        List<Map> getWaybillCargoDetails = SpringManager.getBean(WaybillCargoDetailsRepository.class).qryWaybillCargoDetails(carInformation.getId());
        System.out.println("--------------------------");
        String sourceType = getWaybillCargoDetails.get(0).get("SOURCE_TYPE").toString();
        String origin = getWaybillCargoDetails.get(0).get("ORIGIN").toString();
        if (!"CD0".equals(sourceType)) return;
        JSONObject param = new JSONObject();
        param.put("SYID", origin);
        param.put("XYID", carInformation.getId());
        param.put("DJLXID", "dispatchCar");
        param.put("RYMC", carInformation.getChauffeurId().getName());
        param.put("PHONE", carInformation.getChauffeurId().getMobileNumber());
        try {
            param.put("ZXRQ_SJ", JSON.toJSONStringWithDateFormat(new Date()));
        } catch (Exception e) {
            throw new RuntimeException("日期转换失败" + param);
        }
        getWaybillCargoDetails.stream().forEach(waybillCargoDeatils -> {
            System.out.println(waybillCargoDeatils);
            JSONObject singleItem = new JSONObject();
            singleItem.put("SPID", waybillCargoDeatils.get("PRODUCT_ID"));
            singleItem.put("SL", waybillCargoDeatils.get("LOADING_QTY"));
            singleItem.put("JLDW", waybillCargoDeatils.get("UOM_NAME"));
            itemArray.add(singleItem);
        });
        param.put("item", itemArray);
        outboxSubscriberService.commonSendRequest("local:WaybillService.insertWaybillWLGZ", "WaybillDispatchCar_carInformationId" + carInformation.getId(), param);

    }


    @OutboxSubscriber(id = "local:WaybillService.insertWaybillWLGZ", name = "物流运单生成物流跟踪")
    public void insertWaybillWLGZ(OutboxPayloadWrapper outboxPayloadWrapper) {
        if (switched) return;
        SpringManager.getBean(PiManager.class).synErp("ipmQueryYHDProcessService.insertWaybillPackage", outboxPayloadWrapper.getPayload());
    }

    @OutboxSubscriber(id = "local:waybillService.updateSolicitationQty", name = "修改老框架揽件数量")
    private void updateOldCGDDQty(OutboxPayloadWrapper outboxPayloadWrapper) {
        SpringManager.getBean(PiManager.class).synErp("scmCgddService.updateSolicitationQty", outboxPayloadWrapper.getPayload());
    }

}
